package com.bawei.mall.product.service.impl;

import com.bawei.common.core.constant.ServiceNameConstants;
import com.bawei.common.core.domain.R;
import com.bawei.common.core.exception.ServiceException;
import com.bawei.common.core.utils.DateUtils;
import com.bawei.common.core.utils.bean.BeanUtils;
import com.bawei.common.rabbit.domain.Message;
import com.bawei.common.rabbit.enums.QueueEnum;
import com.bawei.common.security.utils.SecurityUtils;
import com.bawei.es.domain.BulkDeleteDocs;
import com.bawei.es.domain.DocumentReq;
import com.bawei.mall.product.cache.ProductInfoCache;
import com.bawei.mall.product.domain.MallProductInfo;
import com.bawei.mall.product.domain.MallProductRuleInfo;
import com.bawei.mall.product.domain.MallProductSkuInfo;
import com.bawei.mall.product.domain.enums.UnmountEnum;
import com.bawei.mall.product.domain.model.ProductEsInfo;
import com.bawei.mall.product.domain.model.ProductModel;
import com.bawei.mall.product.domain.model.SkuModel;
import com.bawei.mall.product.domain.reponse.ProductDetailsResponse;
import com.bawei.mall.product.domain.reponse.ProductInfoResponse;
import com.bawei.mall.product.domain.request.ProductInfoRequest;
import com.bawei.mall.product.mapper.MallProductInfoMapper;
import com.bawei.mall.product.mapper.MallProductSkuInfoMapper;
import com.bawei.mall.product.service.IMallProductInfoService;
import com.bawei.mall.product.service.IMallProductRuleInfoService;
import com.bawei.mall.product.service.IMallProductSkuInfoService;
import com.bawei.system.remote.api.RemoteEsDocsService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品信息Service业务层处理
 *
 * @author DongZeLiang
 * @date 2022-09-19
 */
@Service
public class MallProductInfoServiceImpl implements IMallProductInfoService
{
    @Autowired
    private MallProductInfoMapper mallProductInfoMapper;

    @Autowired
    private IMallProductSkuInfoService skuInfoService;

    @Autowired
    private IMallProductRuleInfoService ruleInfoService;


    @Autowired
    private ProductInfoCache productInfoCache;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RemoteEsDocsService remoteEsDocsService;

    @Autowired
    private MallProductSkuInfoMapper mallProductSkuInfoMapper;

    /**
     * 查询商品信息
     *
     * @param id 商品信息主键
     * @return 商品信息
     */
    @Override
    public ProductInfoResponse selectMallProductInfoById(Long id)
    {
        MallProductInfo mallProductInfo = mallProductInfoMapper.selectMallProductInfoById(id);
        ProductInfoResponse productInfoResponse = new ProductInfoResponse();
        BeanUtils.copyBeanProp(productInfoResponse, mallProductInfo);
        productInfoResponse.setSkuInfoList(
                skuInfoService.selectMallProductSkuInfoList(new MallProductSkuInfo(){{
                    setProductId(id);
                }})
        );
        return productInfoResponse;
    }

    @Override
    public ProductDetailsResponse selectProductDetailsById (Long productId) {
        if (productId == null || productId == 0){
            throw new ServiceException("查询商品信息，依据不合法！");
        }
        ProductDetailsResponse productDetailsResponse = new ProductDetailsResponse();
        ProductModel productModel = mallProductInfoMapper.selectProductModelById(productId);
        if (productModel == null){
            throw new ServiceException("查询商品信息，商品数据为空");
        }
        productDetailsResponse.setProduct(productModel);
        List<MallProductSkuInfo> mallProductSkuInfos = skuInfoService.selectMallProductSkuInfoList(productId);
        if (mallProductSkuInfos == null || mallProductSkuInfos.size() == 0){
            throw new ServiceException("查询商品信息，SKU数据为空");
        }
        productDetailsResponse.setSkuList(mallProductSkuInfos);
        MallProductRuleInfo ruleInfo = ruleInfoService.selectMallProductRuleInfoById(productModel.getRuleId());
        if (ruleInfo == null){
            throw new ServiceException("查询商品信息，规格数据为空");
        }
        productDetailsResponse.setProductRule(ruleInfo);
        return productDetailsResponse;
    }

    /**
     * 查询商品信息列表
     *
     * @param mallProductInfo 商品信息
     * @return 商品信息
     */
    @Override
    public List<MallProductInfo> selectMallProductInfoList(MallProductInfo mallProductInfo)
    {
        return mallProductInfoMapper.selectMallProductInfoList(mallProductInfo);
    }

    /**
     * 新增商品信息
     *
     * @param productInfoRequest 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertMallProductInfo(ProductInfoRequest productInfoRequest)
    {
        productInfoRequest.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
        productInfoRequest.setCreateTime(DateUtils.getNowDate());
        int i = mallProductInfoMapper.insertMallProductInfo(productInfoRequest);
        if (i == 0){
            return i;
        }

        skuInfoService.batchInsertProductSku(
                SkuModel.builderSkuModel(productInfoRequest.getId(), productInfoRequest.getSkuInfoList())
        );

        // 给搜索系统发送消息需要进行搜索更新
        rabbitTemplate.convertAndSend(QueueEnum.PRODUCT_ADD.queueName(),
                Message.builderMsg(productInfoRequest.getId()));

        return i;
    }

    /**
     * 修改商品信息
     *
     * @param productInfoRequest 商品信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMallProductInfo(ProductInfoRequest productInfoRequest)
    {
        productInfoRequest.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
        productInfoRequest.setUpdateTime(DateUtils.getNowDate());
        int i = mallProductInfoMapper.updateMallProductInfo(productInfoRequest);
        if (i == 0){
            return i;
        }
        skuInfoService.deleteMallProductSkuInfoByProductId(productInfoRequest.getId());
        skuInfoService.batchInsertProductSku(
                SkuModel.builderSkuModel(productInfoRequest.getId(), productInfoRequest.getSkuInfoList())
        );
        return i;
    }

    /**
     * 批量删除商品信息
     *
     * @param ids 需要删除的商品信息主键
     * @return 结果
     */
    @Override
    public int deleteMallProductInfoByIds(Long[] ids)
    {
        skuInfoService.deleteMallProductSkuInfoByProductIds(ids);
        for (Long id : ids) {
            // 延迟执行
            productInfoCache.delayRemove(id);
        }
        return mallProductInfoMapper.deleteMallProductInfoByIds(ids);
    }

    /**
     * 删除商品信息信息
     *
     * @param id 商品信息主键
     * @return 结果
     */
    @Override
    public int deleteMallProductInfoById(Long id)
    {
        return mallProductInfoMapper.deleteMallProductInfoById(id);
    }

    /**
     * 商品总条数
     * @param mallProductInfo 商品查询
     * @return
     */
    @Override
    public Long selectMallProductInfoCount (MallProductInfo mallProductInfo) {
        return mallProductInfoMapper.selectMallProductInfoCount(mallProductInfo);
    }

    /**
     * 上下架
     * @param productId
     * @param status
     */
    @Override
    public void updateStatus(Long productId , String status) {

        String msg;
        R r;

        if(status.equals(UnmountEnum.ON_SALE.getValue())){
            //根据id查询出商品的所有信息
            ProductDetailsResponse productDetails = selectProductDetailsById(productId);
            //商品信息校验
            checkProductInfo(productDetails);

            //组装上架商品信息
            List<ProductEsInfo> productInfos = assembleProduct(productDetails);

            //调用es的服务创建文档
            DocumentReq documentReq = assembleDocInfoReq(productInfos);

            //远程调用es服务上架商品
             r = remoteEsDocsService.bulkDocument(documentReq);
             //修改数据库状态
            mallProductInfoMapper.updateStatus(productId,"0");

            msg ="商品上架失败";

        }else{

            //组装下架需要用的skuId
            BulkDeleteDocs bulkDeleteDocs= assembleDocsIds(productId);

            //远程调用Es接口实现下架
             r = remoteEsDocsService.deleteDocument(bulkDeleteDocs);
            //修改数据库状态
            mallProductInfoMapper.updateStatus(productId,"1");
            msg="商品下架失败";
        }
        if(200!=r.getCode()){
            throw new RuntimeException(msg);
        }



    }

        /**
     * 根据产品ID组装Ids对象
     *
     * @param productId 产品ID
     * @return Ids对象
     */
    private BulkDeleteDocs assembleDocsIds(Long productId) {

        BulkDeleteDocs bulkDeleteDocs = new BulkDeleteDocs();

        bulkDeleteDocs.setIndexName(ServiceNameConstants.PRODUCT_INDEX_NAME);

        // 根据SKU ID查找产品ID列表
        List<Long> ids = mallProductSkuInfoMapper.findProductBySkuId(productId);
        bulkDeleteDocs.setIds(ids);

        return bulkDeleteDocs;
    }


    /**
     * 组装文档信息请求对象
     *
     * @param productInfos 产品信息列表
     * @return 文档信息请求对象
     */
    private DocumentReq assembleDocInfoReq(List<ProductEsInfo> productInfos) {

        // 构建返回体
        DocumentReq result = new DocumentReq();
        // 索引名称
        result.setIndexName(ServiceNameConstants.PRODUCT_INDEX_NAME);
        result.setDocumentId("skuId");


//        将productInfos类型转为map<String,Object>
        List<Map<String, Object>> collect = productInfos.stream().map(product -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id",product.getId());
            map.put("name",product.getName());
            map.put("productDesc",product.getProductDesc());
            map.put("type",product.getType());
            map.put("typeName",product.getTypeName());
            map.put("img",product.getImg());
            map.put("carouselImages",product.getCarouselImages());
            map.put("commentCount",product.getCommentCount());
            map.put("collectCount",product.getCollectCount());
            map.put("brand",product.getBrand());
            map.put("brandName",product.getBrandName());
            map.put("status",product.getStatus());
            map.put("skus",product.getSkus());
            map.put("skuId",product.getSkuId());
            return map;
        }).collect(Collectors.toList());


        result.setDocumentInfo(collect);

        result.setNeedId(true);

        return result;
    }


        /**
     * 构建返回体
     * @param productDetails 商品详情响应对象
     * @return 返回商品EsInfo列表
     */
    private List<ProductEsInfo> assembleProduct(ProductDetailsResponse productDetails) {
        // 构建返回体
        List<ProductEsInfo> productEsInfos = new ArrayList<>();

        // 获取商品信息
        ProductModel product = productDetails.getProduct();
        // 获取sku信息
        List<MallProductSkuInfo> skuList = productDetails.getSkuList();

        for (MallProductSkuInfo mallProductSkuInfo : skuList) {

            ProductEsInfo productEsInfo = new ProductEsInfo();
            // 将商品信息赋值到 es商品对象中
            BeanUtils.copyBeanProp(productEsInfo,product);

            productEsInfo.setSkuId(mallProductSkuInfo.getId());
            productEsInfo.setSkus(mallProductSkuInfo.getSku());
            // 商品信息添加到返回体中
            productEsInfos.add(productEsInfo);
        }
        return productEsInfos;
    }



        private void checkProductInfo(ProductDetailsResponse productDetailsResponse) {
        // 校验商品数据是否为空
        if (productDetailsResponse.getProduct() == null) {
            throw new RuntimeException("商品上架失败,商品数据为空");
        }
        List<MallProductSkuInfo> skuList = productDetailsResponse.getSkuList();
        // 校验商品sku是否为空
        if (skuList == null || skuList.size() == 0) {
            throw new RuntimeException("商品上架失败,商品SKU为空");
        }
    }


}
